
#ifndef _SBUS_H_
#define _SBUS_H_

/* 接收来自遥控器的SBUS信号，解析得到8个通道的指令值，值在1000~2000之间 */
#include <stm32f4xx_hal.h>

#define SBUS_CHANNEL_CNT 16
#define SBUS_FRAME_LEN 25

#define SBUS_FRAME_HEAD 0x0f
#define SBUS_FRAME_END 0x00

#define SBUS_TYPE_HT8A 1
#if SBUS_TYPE_HT8A
/* 对于HT-8A遥控器，SBUS解析通道值如下
 * 通道1：右侧摇杆左右方向，打到最左侧是最小值192，居中为992，打到最右侧是最大值1792 （滚转）
 * 通道2：右侧摇杆上下方向，打到最上侧是最小值192，居中为992，打到最下侧是最大值1792 （俯仰）
 * 通道3：左侧遥感上下方向，打到最下侧是最小值192，居中为992，打到最上侧是最大值1792 （油门）
 * 通道4：左侧摇杆左右方向，打到最左侧是最小值192，居中为992，打到最右侧是最大值1792 （偏航）
 * 通道5：左上侧三段摇杆，打到最外侧是最小值192，居中为992，打到最内侧是最大值1792   （飞行模式，192对应自稳模式，992对应）
 * 通道6：左偏中两段摇杆，打到最外侧是最小值192，打到最内侧是最大值1792             （解锁，192对应上锁状态，1792对应解锁状态）
 * 通道7：右偏中两段摇杆，打到最外侧是最小值192，打到最内侧是最大值1792
 * 通道8：右上侧三段摇杆，打到最外侧是最小值192，居中为992，打到最内侧是最大值1792
 */

#define SBUS_VAL_MIN 192
#define SBUS_VAL_MID 992
#define SBUS_VAL_MAX 1792

#endif

struct sbus_frame
{
    uint8_t head;
    uint16_t channel[SBUS_CHANNEL_CNT];
    uint8_t flags;
    uint8_t end;
};

typedef struct sbus_frame *sbus_frame_t;

/// @brief 使用串口空闲+DMA接收，发现DMA的buffer有一包有效的sbus帧，则写入sbus_frame并返回0，否则返回1
/// @param sbus_frame 成功解析到的SBUS帧
/// @return 成功解析一帧返回0， 否则表示还需要接收字节返回1
int sbus_resovle(sbus_frame_t frame);

/// @brief 开始SBUS监听
/// @param
/// @return
int sbus_run(void);

/// @brief DMA接收到的buffer内可能有SBUS帧，串口中断传调用此函数存储buffer地址和长度
/// 通信线程适时地解析这块buffer，看是否有sbus帧
/// @param byte_buffer
/// @param buf_len
/// @return
int sbus_update_buffer(uint8_t *byte_buffer);

/// @brief 通信线程是否可以去解析一帧
/// @return 可以解析返回0，不可以解析返回1
int sbus_ready_parse();

/// @brief 打印sbus帧，仅用于调试
/// @param frame
/// @return
int sbus_print_frame(sbus_frame_t frame);

/// @brief 获取当前的SBUS帧
/// @param frame
/// @return
int sbus_frame_get(sbus_frame_t frame);

#endif